home *** CD-ROM | disk | FTP | other *** search
- function G_TabbedBrowserWatcher(tabBrowser, name, opt_filterAboutBlank) {
- this.debugZone = "tabbedbrowserwatcher";
- this.tabBrowser_ = tabBrowser;
- this.filterAboutBlank_ = !!opt_filterAboutBlank;
- this.events = G_TabbedBrowserWatcher.events; // Convenience pointer
- G_Assert(this, typeof name == "string" && !!name,
- "Need a probabilistically unique name");
- this.name_ = name;
- this.mark_ = G_TabbedBrowserWatcher.mark_ + "-" + this.name_;
- this.registrar_ = new EventRegistrar(G_TabbedBrowserWatcher.events);
- this.tabbox_ = this.getTabBrowser().mTabBox;
- this.onDOMContentLoadedClosure_ = BindToObject(this.onDOMContentLoaded, this)
- this.tabbox_.addEventListener("DOMContentLoaded",
- this.onDOMContentLoadedClosure_, true);
- this.onDOMNodeInsertedClosure_ = BindToObject(this.onDOMNodeInserted, this);
- this.tabbox_.addEventListener("DOMNodeInserted",
- this.onDOMNodeInsertedClosure_, true);
- this.onTabSwitchClosure_ = BindToObject(this.onTabSwitch, this);
- this.tabbox_.addEventListener("select",
- this.onTabSwitchClosure_, true);
- var win = this.tabbox_.ownerDocument.defaultView;
- this.onChromeUnloadClosure_ = BindToObject(this.onChromeUnload_, this);
- win.addEventListener('unload', this.onChromeUnloadClosure_, false);
- this.lastTab_ = this.getCurrentBrowser();
- this.detectNewTabs_();
- }
- G_TabbedBrowserWatcher.events = {
- DOMCONTENTLOADED: "domcontentloaded",
- LOCATIONCHANGE: "locationchange",
- PAGESHOW: "pageshow",
- PAGEHIDE: "pagehide",
- LOAD: "load",
- UNLOAD: "unload",
- TABLOAD: "tabload",
- TABUNLOAD: "tabunload",
- TABSWITCH: "tabswitch",
- TABMOVE: "tabmove",
- };
- G_TabbedBrowserWatcher.mark_ = "watcher-marked";
- G_TabbedBrowserWatcher.prototype.onChromeUnload_ = function(event) {
- G_Debug(this, "Removing event listeners");
- if (this.tabbox_) {
- this.tabbox_.removeEventListener("DOMContentLoaded",
- this.onDOMContentLoadedClosure_, true);
- this.tabbox_.removeEventListener("DOMNodeInserted",
- this.onDOMNodeInsertedClosure_, true);
- this.tabbox_.removeEventListener("select",
- this.onTabSwitchClosure_, true);
- var win = this.tabbox_.ownerDocument.defaultView;
- win.removeEventListener('unload', this.onChromeUnloadClosure_, false);
- this.tabbox_ = null;
- }
- if (this.lastTab_) {
- this.lastTab_ = null;
- }
- if (this.tabBrowser_) {
- this.tabBrowser_ = null;
- }
- }
- G_TabbedBrowserWatcher.prototype.isInstrumented_ = function(browser) {
- return !!browser[this.mark_];
- }
- G_TabbedBrowserWatcher.prototype.instrumentBrowser_ = function(browser) {
- G_Assert(this, !this.isInstrumented_(browser),
- "Browser already instrumented!");
- new G_BrowserWatcher(this, browser);
- browser[this.mark_] = true;
- }
- G_TabbedBrowserWatcher.prototype.detectNewTabs_ = function() {
- var tb = this.getTabBrowser();
- for (var i = 0; i < tb.browsers.length; ++i)
- this.maybeFireTabLoad(tb.browsers[i]);
- }
- G_TabbedBrowserWatcher.prototype.registerListener = function(eventType,
- listener) {
- this.registrar_.registerListener(eventType, listener);
- }
- G_TabbedBrowserWatcher.prototype.removeListener = function(eventType,
- listener) {
- this.registrar_.removeListener(eventType, listener);
- }
- G_TabbedBrowserWatcher.prototype.fire = function(eventType, e) {
- this.registrar_.fire(eventType, e);
- }
- G_TabbedBrowserWatcher.prototype.fireDocEvent_ = function(eventType,
- doc,
- browser) {
- if (!this.tabBrowser_) {
- G_Debug(this, "Firing event after shutdown: " + eventType);
- return;
- }
- try {
- var isTop = (doc == browser.contentDocument);
- } catch(e) {
- var isTop = undefined;
- }
- var inSelected = (browser == this.getCurrentBrowser());
- var location = doc ? doc.location.href : undefined;
- if (!this.filterAboutBlank_ || location != "about:blank") {
- G_Debug(this, "firing " + eventType + " for " + location +
- (isTop ? " (isTop)" : "") + (inSelected ? " (inSelected)" : ""));
- this.fire(eventType, { "doc": doc,
- "isTop": isTop,
- "inSelected": inSelected,
- "browser": browser});
- }
- }
- G_TabbedBrowserWatcher.prototype.maybeFireTabLoad = function(browser) {
- if (!this.isInstrumented_(browser)) { // Is it a new browser?
- this.instrumentBrowser_(browser); // Add a G_BrowserWatcher
- G_Debug(this, "firing tabload");
- this.fire(this.events.TABLOAD, { "browser": browser });
- }
- }
- G_TabbedBrowserWatcher.prototype.onDOMContentLoaded = function(e) {
- G_Debug(this, "onDOMContentLoaded for a " + e.target);
- var doc = e.target;
- var browser = this.getBrowserFromDocument(doc);
- if (!browser) {
- G_Debug(this, "domcontentloaded: no browser for " + doc.location.href);
- return;
- }
- this.maybeFireTabLoad(browser);
- G_Debug(this, "DOMContentLoaded broken for forward/back buttons.");
- this.fireDocEvent_(this.events.DOMCONTENTLOADED, doc, browser);
- }
- G_TabbedBrowserWatcher.prototype.onDOMNodeInserted = function(e) {
- G_Debug(this, "onDOMNodeInserted for a " + e.target +
- " related: " + e.relatedNode);
- if (e.target.localName != "tab") {
- return;
- }
- if (!isDef(e.target._tPos)) {
- return;
- }
- var fromPos = e.target._tPos;
- var toPos;
- for (var i = 0; i < e.relatedNode.childNodes.length; i++) {
- var child = e.relatedNode.childNodes[i];
- if (child == e.target) {
- toPos = i;
- break;
- }
- }
- G_Debug(this, "firing tabmove");
- this.fire(this.events.TABMOVE, { "tab": e.target,
- "fromIndex": fromPos,
- "toIndex": toPos } );
- }
- G_TabbedBrowserWatcher.prototype.onTabSwitch = function(e) {
- if (e.target == null ||
- (e.target.localName != "tabs" && e.target.localName != "tabpanels"))
- return;
- var fromBrowser = this.lastTab_;
- var toBrowser = this.getCurrentBrowser();
- if (fromBrowser != toBrowser) {
- this.lastTab_ = toBrowser;
- G_Debug(this, "firing tabswitch");
- this.fire(this.events.TABSWITCH, { "fromBrowser": fromBrowser,
- "toBrowser": toBrowser });
- }
- }
- G_TabbedBrowserWatcher.prototype.getTabBrowser = function() {
- return this.tabBrowser_;
- }
- G_TabbedBrowserWatcher.prototype.getCurrentBrowser = function() {
- return this.getTabBrowser().selectedBrowser;
- }
- G_TabbedBrowserWatcher.prototype.getCurrentWindow = function() {
- return this.getCurrentBrowser().contentWindow;
- }
- G_TabbedBrowserWatcher.prototype.getBrowserFromDocument = function(doc) {
- function docInWindow(doc, win) {
- if (win.document == doc)
- return true;
- if (win.frames)
- for (var i = 0; i < win.frames.length; i++)
- if (docInWindow(doc, win.frames[i]))
- return true;
- return false;
- }
- var browsers = this.getTabBrowser().browsers;
- for (var i = 0; i < browsers.length; i++)
- if (docInWindow(doc, browsers[i].contentWindow))
- return browsers[i];
- return null;
- }
- G_TabbedBrowserWatcher.prototype.getDocumentFromURL = function(url,
- opt_browser) {
- function docWithURL(win, url) {
- if (win.document.location.href == url)
- return win.document;
- if (win.frames)
- for (var i = 0; i < win.frames.length; i++) {
- var rv = docWithURL(win.frames[i], url);
- if (rv)
- return rv;
- }
- return null;
- }
- if (opt_browser)
- return docWithURL(opt_browser.contentWindow, url);
- var browsers = this.getTabBrowser().browsers;
- for (var i=0; i < browsers.length; i++) {
- var rv = docWithURL(browsers[i].contentWindow, url);
- if (rv)
- return rv;
- }
- return null;
- }
- G_TabbedBrowserWatcher.prototype.getDocumentsFromURL = function(url,
- opt_browser) {
- var docs = [];
- function getDocsWithURL(win, url) {
- if (win.document.location.href == url)
- docs.push(win.document);
- if (win.frames)
- for (var i = 0; i < win.frames.length; i++)
- getDocsWithURL(win.frames[i], url);
- }
- if (opt_browser)
- return getDocsWithURL(opt_browser.contentWindow, url);
- var browsers = this.getTabBrowser().browsers;
- for (var i=0; i < browsers.length; i++)
- getDocsWithURL(browsers[i].contentWindow, url);
- return docs;
- }
- G_TabbedBrowserWatcher.prototype.getBrowserFromWindow = function(sub) {
- function containsSubWindow(sub, win) {
- if (win == sub)
- return true;
- if (win.frames)
- for (var i=0; i < win.frames.length; i++)
- if (containsSubWindow(sub, win.frames[i]))
- return true;
- return false;
- }
- var browsers = this.getTabBrowser().browsers;
- for (var i=0; i < browsers.length; i++)
- if (containsSubWindow(sub, browsers[i].contentWindow))
- return browsers[i];
- return null;
- }
- G_TabbedBrowserWatcher.getTabElementFromBrowser = function(tabBrowser,
- browser) {
- for (var i=0; i < tabBrowser.browsers.length; i++)
- if (tabBrowser.browsers[i] == browser)
- return tabBrowser.mTabContainer.childNodes[i];
- return null;
- }
- if (G_GDEBUG) {
- G_debugService.loggifier.loggify(G_TabbedBrowserWatcher.prototype);
- }
- function G_BrowserWatcher(tabbedBrowserWatcher, browser) {
- this.debugZone = "browserwatcher";
- this.parent_ = tabbedBrowserWatcher;
- this.browser_ = browser;
- this.onPageShowClosure_ = BindToObject(this.onPageShow, this);
- this.browser_.addEventListener("pageshow", this.onPageShowClosure_, true);
- this.onPageHideClosure_ = BindToObject(this.onPageHide, this);
- this.browser_.addEventListener("pagehide", this.onPageHideClosure_, true);
- this.onLoadClosure_ = BindToObject(this.onLoad, this);
- this.browser_.addEventListener("load", this.onLoadClosure_, true);
- this.onUnloadClosure_ = BindToObject(this.onUnload, this);
- this.browser_.addEventListener("unload", this.onUnloadClosure_, true);
- this.webProgressListener_ = {
- QueryInterface: function() { return this; },
- onLocationChange: bind(this.onLocationChange, this),
- onStateChange: function(){},
- onStatusChange: function(){},
- onSecurityChange: function(){},
- onProgressChange: function(){}
- };
- G_Debug(this, "adding progress listener");
- this.browser_.addProgressListener(this.webProgressListener_,
- Ci.nsIWebProgress.NOTIFY_LOCATION);
- G_Debug(this, "Done");
- }
- G_BrowserWatcher.prototype.onLocationChange = function(webProgress,
- request, location) {
- G_Debug(this, "onLocationChange for {%s}".subs(location.spec));
- if (!this.parent_) {
- G_Debug(this, "onLocationChange after tab close");
- return;
- }
- var e = { browser: this.browser_,
- isTop: true };
- this.parent_.fire(this.parent_.events.LOCATIONCHANGE, e);
- }
- G_BrowserWatcher.prototype.onPageShow = function(e) {
- G_Debug(this, "onPageShow for " + ((e.target) ? (e.target) : ("undefined")));
- if (e.target && e.target.nodeName == "#document") {
- var doc = e.target;
- this.parent_.fireDocEvent_(this.parent_.events.PAGESHOW,
- doc,
- this.browser_);
- }
- }
- G_BrowserWatcher.prototype.onLoad = function(e) {
- G_Debug(this, "onLoad for a " + e.target);
- if (!e.target) {
- G_Debug(this, "e.target is null; canceling onload event");
- return;
- }
- if (e.target.nodeName != "#document")
- return;
- var doc = e.target;
- this.parent_.fireDocEvent_(this.parent_.events.LOAD, doc, this.browser_);
- }
- G_BrowserWatcher.prototype.onUnload = function(e) {
- G_Debug(this, "onUnload for " + ((e.target) ? (e.target) : ("undefined")));
- var doc = e.target;
- if (doc && doc.nodeName == "#document")
- this.parent_.fireDocEvent_("unload", doc, this.browser_);
- if (!doc) { // This is a closing tab
- G_Debug(this, "firing tabunload for a " + this.browser_ + "(" +
- this.browser_.nodename + ")");
- this.parent_.fire(this.parent_.events.TABUNLOAD,
- { "browser": this.browser_ });
- this.browser_.removeEventListener("pageshow", this.onPageShowClosure_, true);
- this.browser_.removeEventListener("pagehide", this.onPageHideClosure_, true);
- this.browser_.removeEventListener("load", this.onLoadClosure_, true);
- this.browser_.removeEventListener("unload", this.onUnloadClosure_, true);
- this.parent_ = null;
- this.browser_ = null;
- G_Debug(this, "Removed event listeners");
- }
- }
- G_BrowserWatcher.prototype.onPageHide = function(e) {
- G_Debug(this, "onPageHide for a " + e.target + "(" +
- e.target.nodeName + ")");
- if (e.target.nodeName != "#document") // Ignore non-documents
- return;
- var doc = e.target;
- this.parent_.fireDocEvent_(this.parent_.events.PAGEHIDE, doc, this.browser_);
- }
-